package com.chukun.gateway.core.config;

import com.chukun.gateway.common.utils.PropertiesUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;

/**
 * @author chukun
 * @version 1.0.0
 * @description 网关运行参数加载器
 * @createTime 2023/11/25 20:43
 */
@Slf4j
public class GatewayConfigLoader {

    private static final String CONFIG_FILE = "gateway.properties";
    private static final String ENV_PREFIX = "GATEWAY_";
    private static final String JVM_PREFIX = "gateway.";

    private static final GatewayConfigLoader INSTANCE = new GatewayConfigLoader();

    private GatewayConfigLoader() {}

    public static GatewayConfigLoader getInstance() {
        return INSTANCE;
    }

    private GatewayConfig config;

    public static GatewayConfig getConfig() {
        return INSTANCE.config;
    }

    /**
     * 优先级高的会覆盖优先级低的
     * 运行参数 -> jvm参数 -> 环境变量 -> 配置文件 -> 配置对象对默认值
     * @param args 运行参数
     * @return 网关的配置信息
     */
    public GatewayConfig load(String[] args) {
        //配置对象对默认值
        config = new GatewayConfig();

        //配置文件
        loadFromConfigFile();

        //环境变量
        loadFromEnv();

        //jvm参数
        loadFromJvm();

        //运行参数
        loadFromArgs(args);

        return config;
    }

    /**
     * 从运行的参数获取配置
     * @param args 运行参数
     */
    private void loadFromArgs(String[] args) {
        if (args == null || args.length == 0) {
            return;
        }
        //--port=1234
        Properties properties = new Properties();
        for (String arg : args) {
            if (arg.startsWith("--") && arg.contains("=")) {
                properties.put(arg.substring(2, arg.indexOf("=")), arg.substring(arg.indexOf("=") + 1));
            }
        }
        PropertiesUtils.properties2Object(properties, config);
    }

    /**
     * jvm参数加载
     */
    private void loadFromJvm() {
        Properties properties = System.getProperties();
        PropertiesUtils.properties2Object(properties, config, JVM_PREFIX);
    }

    /**
     * 环境变量中加载
     */
    private void loadFromEnv() {
        Map<String, String> env = System.getenv();
        Properties properties = new Properties();
        properties.putAll(env);
        PropertiesUtils.properties2Object(properties, config, ENV_PREFIX);
    }

    /**
     * 从默认的配置文件中加载配置
     */
    private void loadFromConfigFile() {
        InputStream inputStream = GatewayConfigLoader.class.getClassLoader().getResourceAsStream(CONFIG_FILE);
        if (inputStream == null) {
            log.warn("loadFromConfigFile.inputStream.empty, path:{}", CONFIG_FILE);
            return;
        }
        Properties properties = new Properties();
        try {
            properties.load(inputStream);
            PropertiesUtils.properties2Object(properties, config);
        } catch (IOException e) {
            log.warn("load config file {} error", CONFIG_FILE, e);
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                log.error("loadFromConfigFile.inputStream.error ", e);
            }
        }
    }

}
